package com.lin.generate.common.utill;

import java.util.Collection;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 字符串处理
 */
public class StrUtils {
    public static String EMPTY_STR = "";

    // 验证手机号
    static Pattern mobilePattern = Pattern.compile("^[1][3,4,5,7,8][0-9]{9}$");
    // 判断小数点后2位的数字的正则表达式
    static Pattern isMoneyPattern = Pattern.compile("^(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?$");

    /**
     * 中文數字转阿拉伯数组【十万九千零六十  --> 109060】
     *
     * @param chineseNumber
     * @return
     */
    public static int chineseNumber2Int(String chineseNumber) {
        int result = 0;
        int temp = 1;
        int count = 0;
        char[] cnArr = new char[]{'一', '二', '三', '四', '五', '六', '七', '八', '九'};
        char[] chArr = new char[]{'十', '百', '千', '万', '亿'};
        for (int i = 0; i < chineseNumber.length(); i++) {
            boolean b = true;
            char c = chineseNumber.charAt(i);
            for (int j = 0; j < cnArr.length; j++) {
                if (c == cnArr[j]) {
                    if (0 != count) {
                        result += temp;
                        temp = 1;
                        count = 0;
                    }
                    temp = j + 1;
                    b = false;
                    break;
                }
            }
            if (b) {
                for (int j = 0; j < chArr.length; j++) {
                    if (c == chArr[j]) {
                        switch (j) {
                            case 0:
                                temp *= 10;
                                break;
                            case 1:
                                temp *= 100;
                                break;
                            case 2:
                                temp *= 1000;
                                break;
                            case 3:
                                temp *= 10000;
                                break;
                            case 4:
                                temp *= 100000000;
                                break;
                            default:
                                break;
                        }
                        count++;
                    }
                }
            }
            if (i == chineseNumber.length() - 1) {
                result += temp;
            }
        }
        return result;
    }

    public static boolean isNull(Object o) {
        return Objects.isNull(o);
    }

    /**
     * 为空
     */
    public static boolean isEmpty(String str) {
        return str == null || EMPTY_STR.equals(str);
    }

    /**
     * 不为空
     */
    public static boolean isNotEmpty(String str) {
        return !isEmpty(str);
    }

    /**
     * 为空
     */
    public static boolean isBlank(String str) {
        return isEmpty(trim(nvl(str)));
    }

    /**
     * 不为空
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    /**
     * 转大写
     */
    public static String toUpperCase(String instr) {
        return instr == null ? instr : instr.toUpperCase();
    }

    /**
     * 转小写
     */
    public static String toLowerCase(String instr) {
        return instr == null ? instr : instr.toLowerCase();
    }

    /**
     * 首字母大写 ,其余不变
     */
    public static String toUpperCaseFirst(String str) {
        if (str == null) {
            return null;
        }
        if (str.length() == 0) {
            return str;
        }
        String pre = String.valueOf(str.charAt(0));
        return str.replaceFirst(pre, pre.toUpperCase());
    }

    /**
     * 首字母小写 ,其余不变
     */
    public static String toLowerCaseFirst(String str) {
        if (str == null) {
            return null;
        }
        if (str.length() == 0) {
            return str;
        }
        String pre = String.valueOf(str.charAt(0));
        return str.replaceFirst(pre, pre.toLowerCase());
    }

    /**
     * 不会抛NullPointerException 的trim() <br>
     * 传入null会返回null
     */
    public static String trim(String str) {
        return str == null ? null : str.trim();
    }

    /**
     * 过滤 ;当instr==null时返回长度为0的""; <br>
     * 与 nvl(...)系的区别在于只处理null ,不处理长度为0的"";
     */
    public static String nvl(String instr) {
        return nvl(instr, EMPTY_STR);
    }

    public static String nvl(Object str) {
        return nvl(Objects.isNull(str) ? null : str.toString());
    }

    /**
     * 过滤 ,把null和长度为0的""当成同一种情况处理; <br>
     * 当instr==null||"".equals(instr)时返回defaultValue ;其它情况返回 instr
     */
    public static String nvl(String instr, String defaultValue) {
        return instr == null || "".equals(instr) ? defaultValue : instr;
    }

    /**
     * 比较 str1 和 str2 如果都是 null 或者 str1.equals(str2) 返回 true 表示一样 ;
     */
    public static boolean equals(String str1, String str2) {
        return Objects.equals(str1, str2);
    }

    /**
     * 返回指定位数的字符串，长度不够按照 toRepeat 补足
     */
    public static String apadLeft(double target, int toRepeat, int len) {
        return apadLeft(String.valueOf(target), String.valueOf(toRepeat), len);
    }

    public static String apadRight(double target, int toRepeat, int len) {
        return apadRight(String.valueOf(target), String.valueOf(toRepeat), len);
    }

    public static String apadLeft(String target, String toRepeat, int len) {
        if (target == null || target.length() == len || toRepeat == null) {
            return target;
        }
        if (target.length() > len) {
            return target.substring(target.length() - len);
        }
        return apadpro(target, toRepeat, len, true);
    }

    public static String apadRight(String target, String toRepeat, int len) {
        if (target == null || target.length() == len || toRepeat == null) {
            return target;
        }
        if (target.length() > len) {
            return target.substring(0, len);
        }
        return apadpro(target, toRepeat, len, false);
    }

    public static String repeatAndJoin(String text, int times) {
        return repeatAndJoin(text, times, "");

    }

    public static String repeatAndJoin(String text, int times, String joinExp) {
        Asserts.check(times > 0, "repeatAndJoin times should be larger then 0.");
        StrBuilderUtil append = StrBuilderUtil.me().append(text);
        for (int i = 0; i < times - 1; i++) {
            append.append(joinExp).append(text);
        }
        return append.toString();

    }


    /**
     * 清除字符串中所有的空格 ,传入null返回null
     */
    public static String clear(String str) {
        return clear(str, " ");
    }

    /**
     * 清除str中出现的所有str2字符序列 直到结果中再也找不出str2为止 str2 == null时 返回str
     */
    public static String clear(String str, String str2) {
        if (str == null) {
            return str;
        }
        if (str2 == null) {
            return str;
        }
        String reg = "(" + str2 + ")+";
        Pattern p = Pattern.compile(reg);
        while (p.matcher(str).find()) {
            str = str.replaceAll(reg, EMPTY_STR);
        }
        return str;
    }


    /**
     * 如果str的长度超过了c则取c-sub.length长度,然后拼上sub结尾
     */
    public static String suojin(String str, int c, String sub) {
        if (isEmpty(str)) {
            return str;
        }
        if (str.length() <= c) {
            return str;
        }
        sub = nvl(sub);
        c = c - sub.length();
        c = c > str.length() ? 0 : c;
        str = str.substring(0, c);
        return StrBuilderUtil.concat(str, sub);
    }

    /**
     * 如果str的长度超过了length,取前length位然后拼上...
     */
    public static String suojin(String str, int length) {
        return suojin(str, length, "…");
    }


    public static String replaceOnce(String target, String searchStr, String replaceStr) {
        return replace(target, searchStr, replaceStr, 1);
    }

    public static String replace(String target, String searchStr, String replaceStr) {
        return replace(target, searchStr, replaceStr, -1);
    }

    public static String replace(String target, String searchStr, String replaceStr, int replaceTimes) {
        if (isEmpty(target) || isEmpty(searchStr) || replaceStr == null || replaceTimes == 0) {
            return target;
        }
        int start = 0;
        int end = target.indexOf(searchStr, start);
        if (end == -1) {
            return target;
        }
        int replLength = searchStr.length();
        int increase = replaceStr.length() - replLength;
        increase = increase >= 0 ? increase : 0;
        increase *= replaceTimes >= 0 ? replaceTimes <= 64 ? replaceTimes : 64 : 16;
        StrBuilderUtil buf = StrBuilderUtil.me();
        do {
            if (end == -1) {
                break;
            }
            buf.append(target.substring(start, end)).append(replaceStr);
            start = end + replLength;
            if (--replaceTimes == 0) {
                break;
            }
            end = target.indexOf(searchStr, start);
        } while (true);
        buf.append(target.substring(start));
        return buf.toString();
    }

//  ========================================private method========================================

    private static String apadpro(String target, String toRepeat, int len, boolean appendleft) {
        int f = len - target.length();
        String appendStr = repeatAndJoin(toRepeat, f);
        return appendleft ? StrBuilderUtil.concat(appendStr, target) : StrBuilderUtil.concat(target, appendStr);
    }

    public static boolean isTrue(Object flag) {
        return Objects.nonNull(flag) && (Boolean.valueOf(flag.toString()) || "1".equals(flag.toString()));
    }

    public static String[] toStrArray(Collection<String> excludeCols) {
        String[] strArray = new String[excludeCols.size()];

        excludeCols.toArray(strArray);

        return strArray;
    }

    /**
     * 手机号验证
     *
     * @param str
     * @return
     */
    public static boolean isMobile(final String str) {
        Matcher m = null;
        boolean b = false;
        m = mobilePattern.matcher(str);
        b = m.matches();
        return b;
    }


    /**
     * 验证是否为金额
     *
     * @param str
     * @return
     */
    public static boolean isAmountOfMoney(String str) {
        Matcher match = isMoneyPattern.matcher(str);
        return match.matches();
    }
}
